package freespiritsocial.io.user.ext

import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.lifecycle.lifecycleOwner
import com.bumptech.glide.Glide
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.resource.bitmap.*
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions
import com.chad.library.adapter.base.BaseQuickAdapter
import com.google.gson.GsonBuilder
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import com.hw.videoprocessor.VideoProcessor
import com.lishuaihua.toast.ToastUtils
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.to.aboomy.pager2banner.Banner
import com.to.aboomy.pager2banner.IndicatorView
import freespiritsocial.io.user.R
import freespiritsocial.io.user.data.model.bean.ApiPagerResponse
import freespiritsocial.io.user.data.model.bean.ApiRefreshResult
import freespiritsocial.io.user.util.CacheUtil
import freespiritsocial.io.user.weight.GlideCircleTransformWithBorderUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import me.hgj.jetpackmvvm.base.appContext
import me.hgj.jetpackmvvm.ext.util.dp2px
import me.hgj.jetpackmvvm.ext.util.loge
import java.io.BufferedReader
import java.io.FileReader
import java.io.IOException
import java.math.BigDecimal
import java.math.RoundingMode
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern

var regEx = ("^(([\\w-]+\\.)+[\\w-]+|([a-zA-Z]{1}|[\\w-]{2,}))@"
        + "((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?"
        + "[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\."
        + "([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?"
        + "[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
        + "([a-zA-Z]+[\\w-]+\\.)+[a-zA-Z]{2,4})$")

/*
* 验证Email是否合法
* */
fun String.validateEmailAddress(): Boolean {
    return Pattern.compile(regEx).matcher(this.trim()).matches()
}


//view 转bitmap
fun convertViewToBitmap(view: View): Bitmap? {
    view.measure(
        View.MeasureSpec.makeMeasureSpec(
            0,
            View.MeasureSpec.UNSPECIFIED
        ),
        View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED)
    )
    view.layout(0,0,view.measuredWidth,view.measuredHeight)
    view.buildDrawingCache()
    return view.drawingCache
}

fun Banner.initDefIndicator(context: Context) {
    val params = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)
    params.addRule(RelativeLayout.ALIGN_PARENT_TOP)
    params.addRule(RelativeLayout.CENTER_HORIZONTAL)
    params.topMargin = dp2px(130)
    setIndicator(
        IndicatorView(context)
            .setIndicatorRatio(11f)
            .setIndicatorRadius(1.2f)
            .setIndicatorSelectedRatio(11f)
            .setIndicatorSelectedRadius(1.2f)
            .setIndicatorSpacing(6f)
            .setIndicatorStyle(IndicatorView.IndicatorStyle.INDICATOR_DASH)
            .setIndicatorColor(Color.WHITE)
            .setIndicatorSelectorColor(0xff09C6B7.toInt())
            .setParams(params)
    )
}

fun Banner.initDefBottomIndicator(context: Context) {

    val params = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)
    params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
    params.addRule(RelativeLayout.CENTER_HORIZONTAL)
    params.bottomMargin = dp2px(50)
    setIndicator(
        IndicatorView(context)
            .setIndicatorRatio(11f)
            .setIndicatorRadius(1.2f)
            .setIndicatorSelectedRatio(11f)
            .setIndicatorSelectedRadius(1.2f)
            .setIndicatorSpacing(6f)
            .setIndicatorStyle(IndicatorView.IndicatorStyle.INDICATOR_DASH)
            .setIndicatorColor(Color.WHITE)
            .setIndicatorSelectorColor(0xff09C6B7.toInt())
            .setParams(params)
    )
}


/**
 * @param message 显示对话框的内容 必填项
 * @param title 显示对话框的标题 默认 温馨提示
 * @param positiveButtonText 确定按钮文字 默认确定
 * @param positiveAction 点击确定按钮触发的方法 默认空方法
 * @param negativeButtonText 取消按钮文字 默认空 不为空时显示该按钮
 * @param negativeAction 点击取消按钮触发的方法 默认空方法
 *
 */
fun AppCompatActivity.showMessage(
    message: String,
    title: String = "温馨提示",
    positiveButtonText: String = "确定",
    positiveAction: () -> Unit = {},
    negativeButtonText: String = "",
    negativeAction: () -> Unit = {}
) {
    MaterialDialog(this)
        .cancelable(false)
        .lifecycleOwner(this)
        .show {
            title(text = title)
            message(text = message)
            positiveButton(text = positiveButtonText) {
                positiveAction.invoke()
            }
            if (negativeButtonText.isNotEmpty()) {
                negativeButton(text = negativeButtonText) {
                    negativeAction.invoke()
                }
            }
        }
}

/**
 * @param message 显示对话框的内容 必填项
 * @param title 显示对话框的标题 默认 温馨提示
 * @param positiveButtonText 确定按钮文字 默认确定
 * @param positiveAction 点击确定按钮触发的方法 默认空方法
 * @param negativeButtonText 取消按钮文字 默认空 不为空时显示该按钮
 * @param negativeAction 点击取消按钮触发的方法 默认空方法
 */
fun Fragment.showMessage(
    message: String,
    title: String = "温馨提示",
    positiveButtonText: String = "确定",
    positiveAction: () -> Unit = {},
    negativeButtonText: String = "",
    negativeAction: () -> Unit = {}
) {
    activity?.let {
        MaterialDialog(it)
            .cancelable(false)
            .lifecycleOwner(viewLifecycleOwner)
            .show {
                title(text = title)
                message(text = message)
                positiveButton(text = positiveButtonText) {
                    positiveAction.invoke()
                }
                if (negativeButtonText.isNotEmpty()) {
                    negativeButton(text = negativeButtonText) {
                        negativeAction.invoke()
                    }
                }
            }
    }
}

/**
 * 获取进程号对应的进程名
 *
 * @param pid 进程号
 * @return 进程名
 */
fun getProcessName(pid: Int): String? {
    var reader: BufferedReader? = null
    try {
        reader = BufferedReader(FileReader("/proc/$pid/cmdline"))
        var processName = reader.readLine()
        if (!TextUtils.isEmpty(processName)) {
            processName = processName.trim { it <= ' ' }
        }
        return processName
    } catch (throwable: Throwable) {
        throwable.printStackTrace()
    } finally {
        try {
            reader?.close()
        } catch (exception: IOException) {
            exception.printStackTrace()
        }

    }
    return null
}

/**
 * 加入qq聊天群
 */
fun Fragment.joinQQGroup(key: String): Boolean {
    val intent = Intent()
    intent.data =
        Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D$key")
    // 此Flag可根据具体产品需要自定义，如设置，则在加群界面按返回，返回手Q主界面，不设置，按返回会返回到呼起产品界面    //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    return try {
        startActivity(intent)
        true
    } catch (e: Exception) {
        // 未安装手Q或安装的版本不支持
        ToastUtils.show("未安装手机QQ或安装的版本不支持")
        false
    }
}

fun View.setTitle(title: String) {
    findViewById<TextView>(R.id.appbar_title)?.text = title
}

/**
 * 拦截登录操作，如果没有登录跳转登录，登录过了贼执行你的方法
 */
fun NavController.jumpByLogin(action: (NavController) -> Unit) {
    if (CacheUtil.isLogin()) {
        action(this)
    } else {
        goLogin()
    }
}


fun NavController.goMain() {
    setGraph(R.navigation.main_navation)
}

fun NavController.goLogin() {
    CacheUtil.token = ""
    setGraph(R.navigation.login_navation)
}


/**
 * 拦截登录操作，如果没有登录执行方法 actionLogin 登录过了执行 action
 */
fun NavController.jumpByLogin(
    actionLogin: (NavController) -> Unit,
    action: (NavController) -> Unit
) {
    if (CacheUtil.isLogin()) {
        action(this)
    } else {
        actionLogin(this)
    }
}


fun List<*>?.isNull(): Boolean {
    return this?.isEmpty() ?: true
}

fun List<*>?.isNotNull(): Boolean {
    return this != null && this.isNotEmpty()
}

fun Double.toBigDecimalPrice(): BigDecimal {
    return this.toBigDecimal().setScale(2,RoundingMode.HALF_UP)
}

fun Long.getTimeFormat(format: String = "hh: mm aa dd/MM/yyyy"): String {
    return SimpleDateFormat(
        format,
        Locale.ENGLISH
    ).format(Date(if (this < 1 * 1000000000000) this * 1000L else this))
}

fun Date.getTimeFormat(format: String = "yyyy-MM-dd"): String {
    return SimpleDateFormat(
        format,
        Locale.ENGLISH
    ).format(this)
}

fun <T> loadListData(
    data: ApiPagerResponse<T>,
    baseQuickAdapter: BaseQuickAdapter<T,*>,
    smartRefreshLayout: SmartRefreshLayout? = null
) {
    smartRefreshLayout?.setEnableLoadMore(data.hasMore())
    if (data.isRefresh())
        baseQuickAdapter.data.clear()
    baseQuickAdapter.addData(data.list)

}

fun <T> loadListData(
    data: ApiRefreshResult<T>,
    baseQuickAdapter: BaseQuickAdapter<T,*>,
    smartRefreshLayout: SmartRefreshLayout? = null
) {
    smartRefreshLayout?.setEnableLoadMore(data.hasMore)
    if (data.isRefresh)
        baseQuickAdapter.data.clear()
    baseQuickAdapter.addData(data.data)
}


/*
* 获取焦点 并弹起输入法
* */
fun EditText.requestFocusable() {
    isFocusable = true
    requestFocus()
    //打开软键盘
    val imm: InputMethodManager = context
        .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.toggleSoftInput(0,InputMethodManager.HIDE_NOT_ALWAYS)
}

/**
 * 根据索引获取集合的child值
 * @receiver List<T>?
 * @param position Int
 * @return T?
 */
inline fun <reified T> List<T>?.getChild(position: Int): T? {
    //如果List为null 返回null
    return if (this == null) {
        null
    } else {
        //如果position大于集合的size 返回null
        if (position + 1 > this.size) {
            null
        } else {
            //返回正常数据
            this[position]
        }
    }
}

//Imageview
fun ImageView.loadImage(url: String?,default: Int = R.drawable.hodler) {
    Glide.with(this).load(url).apply(
        RequestOptions().placeholder(default).centerCrop()
    )/*.transition(DrawableTransitionOptions.withCrossFade(500))*/.into(this)
}

fun ImageView.circleImageUrl(url: String?) {
    Glide.with(this.context)
        .load(url)
        .apply(RequestOptions().centerCrop().transform(CircleCrop()))
        .placeholder(R.drawable.hodler_circle)
        /*.transition(DrawableTransitionOptions.withCrossFade(500))*/
        .into(this)
}

fun ImageView.circleImageUrlWithBorder(url: String?,border: Int = 1) {
    this.tag = url
    if (border == 0) return circleImageUrl(url)
    Glide.with(this.context)
        .load(url)
        .apply(RequestOptions().centerCrop().transform(GlideCircleTransformWithBorderUtils(context,border,0xff09c6b7.toInt())))
        .into(this)
}

fun ImageView.loadImageWithTopCorner(url: String?,corner: Int,default: Int = R.drawable.hodler,transformation: BitmapTransformation = CenterCrop()) {
    Glide.with(this).load(url).apply(
        RequestOptions.bitmapTransform(
            MultiTransformation(
                transformation,
                GranularRoundedCorners(dp2px(corner).toFloat(),dp2px(corner).toFloat(),0f,0f)
            )
        )
            .placeholder(default)
    )/*.transition(DrawableTransitionOptions.withCrossFade(500))*/.into(this)
}

//Imageview
fun ImageView.loadImageWithCorner(url: String?,corner: Int,default: Int = R.drawable.hodler,transformation: BitmapTransformation = CenterCrop()) {
    Glide.with(this).load(url).apply(
        RequestOptions.bitmapTransform(MultiTransformation(transformation,RoundedCorners(dp2px(corner)))).placeholder(default)
    )/*.transition(DrawableTransitionOptions.withCrossFade(500))*/.into(this)
}

fun Int.str() = appContext.getString(this)

val gson by lazy {
    GsonBuilder().registerTypeAdapter(String::class.java,object: TypeAdapter<String>() {
        override fun write(out: JsonWriter?,value: String?) {
            out?.value(value)
        }

        override fun read(`in`: JsonReader?): String {
            if (`in`?.peek() == JsonToken.NULL) {
                `in`.nextNull()
                return ""
            }
            val result = `in`?.nextString()
            return if (result.isNullOrEmpty()) {
                ""
            } else
                result
        }
    }).create()
}

suspend fun Context.processorVideo(path: String,outW: Int = 1280,outH: Int = 720) = withContext(Dispatchers.IO) {
    val outPath = cacheDir.absolutePath.plus("/${System.currentTimeMillis()}.mp4")
    outPath.loge("csw")
    VideoProcessor.processor(this@processorVideo).input(path).output(outPath).outHeight(outH).outWidth(outW)
        .frameRate(20)
        .iFrameInterval(2)
        .process()
    return@withContext outPath
}